<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Constants\ErrorCode;
use App\CustHub\Amqp\Producers\SendRecordProducers;
use App\CustHub\Constants\RobotApplyConstants;
use App\CustHub\Constants\SendConfigConstants;
use App\CustHub\Dto\SendRecordProducersDto;
use App\CustHub\Mapper\ChCorpMapper;
use App\CustHub\Mapper\ChRobotMapper;
use App\CustHub\Mapper\ChSopMapper;
use App\CustHub\Model\ChChatRecord;
use App\CustHub\Model\ChContact;
use App\CustHub\Model\ChRobot;
use App\CustHub\Model\ChRoom;
use App\CustHub\Model\ChSop;
use App\CustHub\Model\ChSopSendTask;
use App\CustHub\Model\ChSopSendTaskMain;
use App\CustHub\Model\ChSopSubTask;
use App\CustHub\Model\ChSopTemplate;
use App\Exception\BusinessException;
use Hyperf\Amqp\Producer;
use Hyperf\Coroutine\Coroutine;
use Hyperf\DbConnection\Db;
use Mine\Abstracts\AbstractService;
use Hyperf\Di\Annotation\Inject;
use function Hyperf\Collection\collect;
use function Hyperf\Collection\data_get;
use function Hyperf\Coroutine\co;

class ChSopService extends AbstractService
{

    public $mapper;

    #[Inject]
    protected ChSendConfigService $sendService;

    #[Inject]
    protected ChRobotApplyService $applyService;

    #[Inject]
    protected ChCrowSendingService $SendingService;

    #[Inject]
    protected ChContactService $contactService;

    #[Inject]
    protected ChCorpTagService $corpTagService;

    #[Inject]
    protected ChCorpMapper $chCorpMapper;

    #[Inject]
    protected ChRoomTagService $ChRoomTagService;

    #[Inject]
    protected ChSmartTagService $ChSmartTagService;

    public function __construct(ChSopMapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function afterEditTemplate(ChSopTemplate $template):void
    {
        $data=[
            'template_type'=>$template -> template_type,
            'is_return'=>$template -> is_return,
            'return_code'=>$template -> return_code,
            'return_text'=>$template -> return_text,
        ];
        $data['plan']=json_encode($template['plan']);
        ChSop::query()->where('template_id',$template->id)->update($data);
        $dayTotal = count($template['plan']);
        $data['day']=$dayTotal;
        //更新计划任务
        co(function () use ($template,$data) {
            unset($data['plan']);
            //更新主任务
            Db::transaction(function () use ($template,$data) {
                ChSopSendTaskMain::query() -> where('template_id',$template->id)->where('status',1)->chunk(100, function ($tasks) use($template,$data){
                    $plan = $template['plan'];
                    $templateType = $template['template_type'];
                    //1.查询进行中的任务
                    //2.查询当天进行中的任务修改
                    //3.查询当天没有任务新增
                    //4.删除不在新的计划里面并且进行中任务
                    $days=[];
                    $preDay=0;
                    foreach ($tasks as $mainTask) {
                        ChSopSendTaskMain::query() ->where('id',$mainTask->id)->update($data);
                        $sop=ChSop::query() ->where('id',$mainTask->sop_id)->first();
                        $startDay=$sop->start_day;
                        foreach ($plan as $key => $item) {
                            $isLast=0;
                            $isSend=0;
                            if($key+1==count($plan)) $isLast=1;
                            //跳过的全部改成已跳过
                            if ($item['day'] < $startDay && $templateType == 1){
                                $isSend=2;
                            }
                            $days[]=$item['day'];
                            $oldTask=ChSopSendTask::query()->where('task_main_id',$mainTask->id)->where('day',$item['day'])->first();
                            if(!empty($oldTask) && $oldTask->is_send == 1){
                                if($key == 0){
                                    $triggerDay=date('Y-m-d',strtotime($oldTask['start_time']));
                                }
                                $preDay = $item['day'];
                                continue;
                            }
                            if ($key == 0) {
                                //首日
                                switch ($templateType) {
                                    case 1:
                                        $triggerDay = date("Y-m-d", time());
                                        if ($item['send_type'] == 1) {
                                            //时间段随机时间发送
                                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                                        } else {
                                            //指定时间点发送
                                            $start_time = $triggerDay . " " . $item['content'][0]['extra']['send_time'];
                                        }
                                        break;
                                    case 2:
                                        if ($item['send_type'] == 1) {
                                            //打上标签后开始任务
                                            $second = $item['conf']['before_hour'] * 3600 + $item['conf']['before_minute'] * 60;
                                            $triggerDay = date("Y-m-d", time() + $second);
                                            $start_time = date("Y-m-d H:i:s", time() + $second);
                                        } else if ($item['send_type'] == 2) {
                                            //打上标签后随机开始发送任务
                                            $triggerDay = date("Y-m-d", strtotime('+' . $item['conf']['before_day'] . " day", time()));
                                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                                        } else if ($item['send_type'] == 3) {
                                            //指定时间开始任务
                                            $triggerDay = $item['conf']['appoint_day'];
                                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                                        }
                                        break;
                                    case 3:
                                        if ($item['send_type'] == 1) {
                                            //加为好友后开始任务
                                            $second = $item['conf']['before_hour'] * 3600 + $item['conf']['before_minute'] * 60;
                                            $triggerDay = date("Y-m-d", time() + $second);
                                            $start_time = date("Y-m-d H:i:s", time() + $second);
                                        } else if ($item['send_type'] == 2) {
                                            //加为好友后随机开始发送任务
                                            $triggerDay = date("Y-m-d", strtotime('+' . $item['conf']['before_day'] . " day", time()));
                                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                                        }
                                        break;
                                    case 4:
                                        if ($item['send_type'] == 1) {
                                            //满足条件后开始任务
                                            $second = $item['conf']['before_hour'] * 3600 + $item['conf']['before_minute'] * 60;
                                            $triggerDay = date("Y-m-d", time() + $second);
                                            $start_time = date("Y-m-d H:i:s", time() + $second);
                                        } else if ($item['send_type'] == 2) {
                                            //满足条件后随机开始发送任务
                                            $triggerDay = $item['conf']['appoint_day'];
                                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                                        }
                                        break;
                                }
                                $mainTask -> next_at = $start_time;
                                $mainTask->save();
                            } else {
                                //var_dump($triggerDay."-----".$item['day']);
                                if (empty($triggerDay)) {
                                    $triggerDay = date("Y-m-d", time());
                                } else {
                                    $day = $item['day']-$preDay;
                                    $triggerDay = date("Y-m-d", strtotime('+' . $day . " day", strtotime($triggerDay)));
                                }
                                if ($item['send_type'] == 1) {
                                    //时间段随机时间发送
                                    $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                                    $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                                    $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                                } else {
                                    //指定时间点发送
                                    $start_time = $triggerDay . " " . $item['content'][0]['extra']['send_time'];
                                }
                            }
                            //追踪统计时间
                            $track_time=null;
                            if($mainTask->is_track==1){
                                $track_time=strtotime($start_time)+$mainTask->track_limit*60;
                            }
                            if(empty($oldTask)){
                                $this->createTask($sop, $mainTask->to_id, $mainTask->robot_id,$item['content'], $start_time, $item['day'],$mainTask->id,$sop->is_track,$track_time,$mainTask->is_room,$isLast,$isSend);
                            }else{
                                $this->updateTask($oldTask,$sop, $mainTask->to_id, $mainTask->robot_id,$item['content'], $start_time, $item['day'],$mainTask->id,$sop->is_track,$track_time,$mainTask->is_room,$isLast,$isSend);
                            }
                            $preDay = $item['day'];
                        }
                        ChSopSendTask::query()->where('task_main_id',$mainTask->id)->where('is_send',0)->whereNotIn('day',$days)->delete();
                    }
                });
            });
        });
    }

    /**
     * @param ChSop $sop sop信息
     * @param array $plan 计划
     * @param $templateType 模板类型
     * @param $robotId  机器人
     * @param $toId       对象用户
     * @param $startDay   从第几天开始
     * @param $triggerTime 触发时间
     * @param int $isRoom
     */
    public function createPlan(ChSop $sop, array $plan, $templateType, $toId,$robotId, $startDay = 0, $triggerTime = null, $isRoom = 0,$subTaskId=0)
    {
        //创建主任务id
        $dayTotal = count($plan);
        foreach ($plan as $key => $item) {
            if($item['day']==$startDay){
                $dayTotal=$dayTotal-$key;
                continue;
            }
        }
        if($isRoom){
            $objectName = ChRoom::query()->where('room_wxid',$toId)->value('room_name');
        }else{
            $objectName = ChContact::query()->where('user_id',$toId)->value('nickname');
        }
        //查询用户是否已经触发了任务
        $log=ChSopSendTaskMain::query()->where('sop_id',$sop->id)->where('robot_id',$robotId)->where('to_id',$toId)->where('template_type',$sop->template_type)->where('is_room',$isRoom)->where('status',1)->first();
        if($log) {
            return true;
        }
//        }else{
//            //如果是标签sop要排除新客户sop触发的
//            if(ChSopSendTaskMain::query()->where('sop_id',$sop->id)->where('robot_id',$robotId)->where('to_id',$toId)->where('template_type',3)->where('tirgger_type',3)->where('is_room',$isRoom)->where('status',1)->first()){
//                return true;
//            }
//        }
        $mainTask = ChSopSendTaskMain::saveMain($sop,$robotId,$toId,$dayTotal,$objectName,$sop->tirgger_type,$sop->is_return,$sop->return_text,$sop->return_code,$sop->track_limit,$sop->is_track,$isRoom,$subTaskId);
        //sop统计对象+1
        if($isRoom){
            $sop->increment('crowd_total');
        }else{
            $sop->increment('custom_total');
        }
        $preDay = 0;
        foreach ($plan as $key => $item) {
            $isLast=0;
            $isSend=0;
            if($key+1==count($plan)) $isLast=1;
            //跳过的全部改成已跳过
            if ($item['day'] < $startDay && $templateType == 1){
                $isSend=2;
            }
            if ($key == 0) {
                //首日
                switch ($templateType) {
                    case 1:
                        $triggerDay = date("Y-m-d", $triggerTime);
                        if ($item['send_type'] == 1) {
                            //时间段随机时间发送
                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                        } else {
                            //指定时间点发送
                            $start_time = $triggerDay . " " . $item['content'][0]['extra']['send_time'];
                        }
                        break;
                    case 2:
                        if ($item['send_type'] == 1) {
                            //打上标签后开始任务
                            $second = $item['conf']['before_hour'] * 3600 + $item['conf']['before_minute'] * 60;
                            $triggerDay = date("Y-m-d", time() + $second);
                            $start_time = date("Y-m-d H:i:s", time() + $second);
                        } else if ($item['send_type'] == 2) {
                            //打上标签后随机开始发送任务
                            $triggerDay = date("Y-m-d", strtotime('+' . $item['conf']['before_day'] . " day", $triggerTime));
                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                        } else if ($item['send_type'] == 3) {
                            //指定时间开始任务
                            $triggerDay = $item['conf']['appoint_day'];
                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                        }
                        break;
                    case 3:
                        if ($item['send_type'] == 1) {
                            //加为好友后开始任务
                            $second = $item['conf']['before_hour'] * 3600 + $item['conf']['before_minute'] * 60;
                            $triggerDay = date("Y-m-d", time() + $second);
                            $start_time = date("Y-m-d H:i:s", time() + $second);
                        } else if ($item['send_type'] == 2) {
                            //加为好友后随机开始发送任务
                            $triggerDay = date("Y-m-d", strtotime('+' . $item['conf']['before_day'] . " day", $triggerTime));
                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                        }
                        break;
                    case 4:
                        if ($item['send_type'] == 1) {
                            //满足条件后开始任务
                            $second = $item['conf']['before_hour'] * 3600 + $item['conf']['before_minute'] * 60;
                            $triggerDay = date("Y-m-d", time() + $second);
                            $start_time = date("Y-m-d H:i:s", time() + $second);
                        } else if ($item['send_type'] == 2) {
                            //满足条件后随机开始发送任务
                            $triggerDay = $item['conf']['appoint_day'];
                            $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                            $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                            $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                        }
                        break;
                }
                $mainTask -> next_at = $start_time;
                $mainTask->save();
            } else {
                var_dump($triggerDay."-----".$item['day']);
                if (empty($triggerDay)) {
                    $triggerDay = date("Y-m-d", $triggerTime);
                } else {
                    $day = $item['day']-$preDay;
                    $triggerDay = date("Y-m-d", strtotime('+' . $day . " day", strtotime($triggerDay)));
                }
                if ($item['send_type'] == 1) {
                    //时间段随机时间发送
                    $send_time_start = $triggerDay . " " . $item['conf']['send_time_start'] ?? "08:00";
                    $send_time_end = $triggerDay . " " . $item['conf']['send_time_end'] ?? "10:00";
                    $start_time = randomDate(strtotime($send_time_start), strtotime($send_time_end), "Y-m-d H:i");
                } else {
                    //指定时间点发送
                    $start_time = $triggerDay . " " . $item['content'][0]['extra']['send_time'];
                }
            }
            //追踪统计时间
            $track_time=null;
            if($sop->is_track==1){
                $track_time=strtotime($start_time)+$sop->track_limit*60;
            }
            $this->createTask($sop, $toId, $robotId,$item['content'], $start_time, $item['day'],$mainTask->id,$sop->is_track,$track_time,$isRoom,$isLast,$isSend);
            $preDay = $item['day'];
        }

        //判断是否需要循环发送
        $mainTaskList=ChSopSendTask::query()-> where('task_main_id',$mainTask->id)->orderBy('day')->get();
        if($sop->is_loop && $mainTaskList->count() == 1 && strtotime($mainTaskList[0]->start_time)<time()){
            $this->setTaskLoop($mainTaskList,$mainTask);
        }
    }

    protected function setTaskLoop($mainTaskList,$mainTask)
    {
        $nextTime=null;
        foreach ($mainTaskList as $key=>$subTask)
        {
            $day=$mainTaskList[$mainTaskList->count()-1]->day;
            $subTask->start_time=date("Y-m-d H:i:s", strtotime($subTask->start_time."+".$day." day"));
            if($subTask->is_track==1){
                $subTask->track_time=strtotime($subTask->start_time)+$mainTask->track_limit*60;
            }
            $subTask->loop_times=$subTask->loop_times+1;
            $subTask->is_send=0;
            $subTask->status=1;
            $subTask->save();
            if($key==0){
                $nextTime=$subTask->start_time;
            }
        }
        ChSopSendTaskMain::query()->where('id',$mainTask->id)->update([
            'status'=>1,
            'complate_day'=>0,
            'next_at'=>$nextTime
        ]);
    }

    /**
     * 创建计划任务
     */
    public function createTask(ChSop $sop, $toId, $robotId,$content, $startTime, $day,$task_main_id,$is_track=0,$track_time=null,$isRoom = 0,$is_last=0,$is_send=0)
    {
        $task = new ChSopSendTask();
        $task->main_uid = $sop->main_uid;
        $task->uid = $sop->uid;
        $task -> robot_id = $robotId;
        $task->sop_id = $sop->id;
        $task->to_id = $toId;
        $task->is_room = $isRoom;
        $task->status = 1;
        $task->template_type = $sop->template_type;
        $task->content = $content;
        $task->task_main_id = $task_main_id;
        $task->start_time = $startTime;
        if(strtotime($startTime)<time()){
            $task->status = 2;
        }
        $task->day = $day;
        $task->is_last = $is_last;
        $task->is_track = !$isRoom?$is_track:0;
        $task->track_time = $track_time;
        $task->is_send = $is_send;
        $task->save();
    }

    public function updateTask(ChSopSendTask $task,ChSop $sop, $toId, $robotId,$content, $startTime, $day,$task_main_id,$is_track=0,$track_time=null,$isRoom = 0,$is_last=0,$is_send=0)
    {
        $task->main_uid = $sop->main_uid;
        $task->uid = $sop->uid;
        $task -> robot_id = $robotId;
        $task->sop_id = $sop->id;
        $task->to_id = $toId;
        $task->is_room = $isRoom;
        $task->status = 1;
        $task->template_type = $sop->template_type;
        $task->content = $content;
        $task->task_main_id = $task_main_id;
        $task->start_time = $startTime;
        if(strtotime($startTime)<time()){
            $task->status = 2;
        }
        $task->day = $day;
        $task->is_last = $is_last;
        $task->is_track = !$isRoom?$is_track:0;
        $task->track_time = $track_time;
        $task->is_send = $is_send;
        $task->save();
    }


    /**
     * @param $startDay //从第几天开始
     * 触发标准sop(直接触发)
     */
    public function triggerStandardSop(ChSop $sop, $templateType,$robotIds, $startDay = 0)
    {
        $plan = $sop->plan;
        //标准sop 直接触发
        co(function () use ($sop, $plan, $templateType, $startDay,$robotIds) {
            Db::beginTransaction();
            //$robotIds = $this->applyService->getApplyRobot(RobotApplyConstants::SOP, $sop->id);
            try {
                //查询发送客户
                if($sop -> send_type == 1){
                    //根据不同的机器人取出客户数据
                    $customRobotIds = $sop -> custom_ids;
                    $crowdRobotIds = $sop -> crowd_ids;
                    foreach ($customRobotIds as $robotInfo) {
                        if(empty($robotInfo['wxids']) || empty($robotInfo['robot_id'])) continue;
                        $contacts = $robotInfo['wxids'];
                        $robotId=$robotInfo['robot_id'];
                        $custom_total=!empty($contacts)?count($contacts):0;
                        $subTask=ChSopSubTask::saveSubTask($sop,$robotId,$custom_total,0,$custom_total);
                        //创建子任务
                        foreach ($contacts as $contact) {
                            $this->createPlan($sop, $plan, $templateType, $contact,$robotId, $startDay, time(),0,$subTask->id);
                        }
                    }
                    foreach ($crowdRobotIds as $robotInfo) {
                        if(empty($robotInfo['wxids']) || empty($robotInfo['robot_id'])) continue;
                        $crowds = $robotInfo['wxids'];
                        $robotId=$robotInfo['robot_id'];
                        $crowd_total=!empty($crowds)?count($crowds):0;
                        $subTask=ChSopSubTask::saveSubTask($sop,$robotId,0,$crowd_total,$crowd_total);
                        //创建子任务
                        foreach ($crowds as $crowd) {
                            $this->createPlan($sop, $plan, $templateType, $crowd, $robotId,$startDay, time(), 1,$subTask->id);
                        }
                    }
                }else{
                    foreach ($robotIds as $robotId) {
                        $custom_conf=$sop->condition_conf['custom_conf'];
                        $custom_conf['conf']=$custom_conf['conf']?[$custom_conf['conf']]:[];
                        $crowd_conf=$sop->condition_conf['crowd_conf'];
                        $crowd_conf['conf']=$crowd_conf['conf']?[$crowd_conf['conf']]:[];
                        $contacts = $this->SendingService->getContactList($robotId, $sop->uid, $custom_conf);
                        $crowds = $this->SendingService->getCrowdList($robotId, $sop->uid,$sop->main_uid,$crowd_conf);
                        //创建子任务
                        $custom_total=!empty($contacts)?count($contacts):0;
                        $crowd_total=!empty($crowds)?count($crowds):0;
                        $total=$custom_total+$crowd_total;
                        $subTask=ChSopSubTask::saveSubTask($sop,$robotId,$custom_total,$crowd_total,$total);
                        foreach ($contacts as $contact) {
                            $this->createPlan($sop, $plan, $templateType, $contact,$robotId, $startDay, time(),0,$subTask->id);
                        }
                        foreach ($crowds as $crowd) {
                            $this->createPlan($sop, $plan, $templateType, $crowd, $robotId,$startDay, time(), 1,$subTask->id);
                        }
                    }
                }
                $sop->status=2;
                $sop->save();
                Db::commit();
            } catch (\Throwable $ex) {
                Db::rollBack();
                throw New BusinessException(ErrorCode::SERVICE_ERROR,$ex -> getMessage());
            }

        });
    }


    /**
     * 批量触发群邀请
     */
    public function branchTriggerTagSop($ids)
    {
        ChContact::query()->whereIn('id',$ids)->get()->each(function($contact){
            //队列里去触发 todo
            $this->triggerTagSop($contact);
        });
    }

    /**
     * @param
     * 用户修改标签的时候调用
     * 触发标签sop
     */
    public function triggerTagSop(ChContact $contact)
    {
        Db::beginTransaction();
        try {
            $targetSop = null;
            $contactId=$contact->user_id;
            $corpId=$contact->corp_id;
            $corpTags=$contact->corpTags()->pluck('corp_tag_id')->toArray();
            $smartTags=$contact->smartTags()->pluck('smart_tag_id')->toArray();
            $ids=$this->applyService->getApplyTargetIds(RobotApplyConstants::SOP,$contact->robot_id);

            $list = ChSop::query()  -> whereIn('id',$ids)  -> where('status',1) -> where(function($q){
                $q->where('template_type',2);
            })->get();
            //按企业标签触发 每种类型只触发一个
            foreach ($list as $key => $item){
                //标识是否满足条件
                $flag=false;
                //企业标签
                if(not_empty($item['trigger_tag']['enterprise_tag_type']) && !empty($item['trigger_tag']['enterprise_tag'])){
                    logger()->info('标签sop配置的企业标签:'.json_encode($item['trigger_tag']['enterprise_tag']));
                    if(!empty($item['trigger_tag']['enterprise_tag'][0]['corp_id'])){
                        $corp_tag_ids = array_unique(array_merge(...array_column($item['trigger_tag']['enterprise_tag'], 'ids')));
                    }else{
                        $corp_tag_ids=$item['trigger_tag']['enterprise_tag'];
                    }
                    if($item['trigger_tag']['enterprise_tag_type'] == 1){
                        //包含任意
                        if(array_intersect($corp_tag_ids,$corpTags)){
                            $flag=true;
                        }
                    }else{
                        //包含所有
                        if(empty(array_diff($corp_tag_ids, $corpTags))){
                            $flag=true;
                        }
                    }
                }
                //智能标签
                logger()->info('标签sop配置的智能标签:'.json_encode($item['trigger_tag']['enterprise_tag']));
                if(not_empty($item['trigger_tag']['smart_tag_type']) && !empty($item['trigger_tag']['smart_tag'])){
                    if($item['trigger_tag']['smart_tag_type'] == 1){
                        //包含任意
                        if(array_intersect($item['trigger_tag']['smart_tag'],$smartTags)){
                            $flag=true;
                        }
                    }else{
                        //包含所有
                        if(empty(array_diff($item['trigger_tag']['smart_tag'], $smartTags))){
                            $flag=true;
                        }
                    }
                }

                if($item['open_out_tag'] == 1){
                    //开启排除标签
                    if(!empty($item['out_tag']['enterprise_tag_type']) && !empty($item['out_tag']['enterprise_tag'])){
                        //排除企业标签
                        if(!empty($item['out_tag']['enterprise_tag'][0]['corp_id'])){
                            $corp_tag_ids = array_unique(array_merge(...array_column($item['out_tag']['enterprise_tag'], 'ids')));
                        }else{
                            $corp_tag_ids=$item['out_tag']['enterprise_tag'];
                        }
                        if($item['out_tag']['enterprise_tag_type'] == 1){
                            //包含任意
                            if(array_intersect($corp_tag_ids,$corpTags)){
                                $flag=false;
                            }
                        }else{
                            //包含所有
                            if(empty(array_diff($corp_tag_ids, $corpTags))){
                                $flag=false;
                            }
                        }
                    }
                    //排除只能标签
                    if(!empty($item['out_tag']['smart_tag_type']) && !empty($item -> out_tag['smart_tag'])){
                        //排除企业标签
                        if($item['out_tag']['smart_tag_type'] == 1){
                            //包含任意
                            if(array_intersect($item['out_tag']['smart_tag'],$smartTags)){
                                $flag=false;
                            }
                        }else{
                            //包含所有
                            if(empty(array_diff($item['out_tag']['smart_tag'], $smartTags))){
                                $flag=false;
                            }
                        }
                    }
                }
                if(!$flag){
                    unset($list[$key]);
                }
            }
            $list->isNotEmpty() && $targetSop = $list->random(1)->first();
            if($targetSop){
                logger()->info('标签sop触发成功'.$targetSop['id']);
                //触发sop
                $robotIds=$this -> applyService -> getApplyRobot(SendConfigConstants::SOP,$targetSop['id']);
                if(!empty($robotIds)){
                    $robotIds=$robotIds->toArray();
                    $robotId=$robotIds[array_rand($robotIds)];
                    $this->createPlan($targetSop, $targetSop['plan'], $targetSop['template_type'], $contactId, $robotId,0, time());
                }
                Db::commit();
                return true;
            }
            Db::commit();
        } catch (\Throwable $ex) {
            Db::rollBack();
            throw New BusinessException(ErrorCode::SERVICE_ERROR,$ex -> getMessage());
        }
    }

    /**
     * 触发新用户sop
     */
    public function triggerNewSop(ChContact $contact)
    {
        logger()->info('触发新用户sop'.$contact['id']);
        Db::beginTransaction();
        try {
            $contactId=$contact->user_id;
            $corpId=$contact->corp_id;
            //$sopIds = $this -> applyService -> getApplyTargetIds(SendConfigConstants::SOP,$robotId);
            $targetSop = null;
            $corpTags=$contact->corpTags()->pluck('corp_tag_id')->toArray();
            $smartTags=$contact->smartTags()->pluck('smart_tag_id')->toArray();
            logger()->info('新用户sop用户企业标签'.json_encode($corpTags));
            logger()->info('新用户sop用户智能标签'.json_encode($smartTags));
            $ids=$this->applyService->getApplyTargetIds(RobotApplyConstants::SOP,$contact->robot_id);
            //按性别触发 每种类型只触发一个
            $list = ChSop::query() -> whereIn('id',$ids) -> where('status',1) -> where('template_type',3) ->  where('tirgger_type',1) -> get();
            foreach ($list as $key => $item){
                $trigger_condition = $item->trigger_condition;
                if(!in_array($contact -> gender,$trigger_condition['sex'])){
                    unset($list[$key]);
                }
            }
            $list->isNotEmpty() && $targetSop = $list->random(1)->first();
            if($targetSop){
                logger()->info('新用户sop按性别触发成功'.$targetSop['id']);
                //触发sop
                $robotIds=$this -> applyService -> getApplyRobot(SendConfigConstants::SOP,$targetSop['id']);
                if(!empty($robotIds)){
                    $robotIds=$robotIds->toArray();
                    $robotId=$robotIds[array_rand($robotIds)];
                    $this->createPlan($targetSop, $targetSop['plan'], $targetSop['template_type'], $contactId, $robotId,0, time());
                }
                Db::commit();
                return true;
            }
            //直接触发 每种类型只触发一个
            $list = ChSop::query()  -> whereIn('id',$ids) -> where('status',1) -> where('template_type',3)  -> where('tirgger_type',2) -> get();
            $list->isNotEmpty() && $targetSop = $list->random(1)->first();
            if($targetSop){
                logger()->info('新用户sop直接触发成功'.$targetSop['id']);
                //触发sop
                $robotIds=$this -> applyService -> getApplyRobot(SendConfigConstants::SOP,$targetSop['id']);
                if(!empty($robotIds)){
                    $robotIds=$robotIds->toArray();
                    $robotId=$robotIds[array_rand($robotIds)];
                    $this->createPlan($targetSop, $targetSop['plan'], $targetSop['template_type'], $contactId, $robotId,0, time());
                }
                Db::commit();
                return true;
            }

            $list = ChSop::query()  -> whereIn('id',$ids) -> where('status',1) -> where('template_type',3)  -> where('tirgger_type',3) -> get();
            //按企业标签触发 每种类型只触发一个
            foreach ($list as $key => $item){
                //标识是否满足条件
                $flag=false;
                //企业标签
                if(not_empty($item['trigger_tag']['enterprise_tag_type']) && !empty($item['trigger_tag']['enterprise_tag'])){
                    logger()->info('新用户sop配置的企业标签:'.json_encode($item['trigger_tag']['enterprise_tag']));
                    if(!empty($item['trigger_tag']['enterprise_tag'][0]['corp_id'])){
                        $corp_tag_ids = array_unique(array_merge(...array_column($item['trigger_tag']['enterprise_tag'], 'ids')));
                    }else{
                        $corp_tag_ids=$item['trigger_tag']['enterprise_tag'];
                    }
                    if($item['trigger_tag']['enterprise_tag_type'] == 1){
                        //包含任意
                        if(array_intersect($corp_tag_ids,$corpTags)){
                            $flag=true;
                        }
                    }else{
                        //包含所有
                        if(empty(array_diff($corp_tag_ids, $corpTags))){
                            $flag=true;
                        }
                    }

                }
                //智能标签
                logger()->info('新用户sop配置的智能标签:'.json_encode($item['trigger_tag']['enterprise_tag']));
                if(not_empty($item['trigger_tag']['smart_tag_type']) && !empty($item['trigger_tag']['smart_tag'])){
                    if($item['trigger_tag']['smart_tag_type'] == 1){
                        //包含任意
                        if(array_intersect($item['trigger_tag']['smart_tag'],$smartTags)){
                            $flag=true;
                        }
                    }else{
                        //包含所有
                        if(empty(array_diff($item['trigger_tag']['smart_tag'], $smartTags))){
                            $flag=true;
                        }
                    }
                }

                if($item['open_out_tag'] == 1){
                    //开启排除标签
                    if(!empty($item['out_tag']['enterprise_tag_type']) && !empty($item['out_tag']['enterprise_tag'])){
                        if(!empty($item['out_tag']['enterprise_tag'][0]['corp_id'])){
                            $corp_tag_ids = array_unique(array_merge(...array_column($item['out_tag']['enterprise_tag'], 'ids')));
                        }else{
                            $corp_tag_ids=$item['out_tag']['enterprise_tag'];
                        }
                        //排除企业标签
                        if($item['out_tag']['enterprise_tag_type'] == 1){
                            //包含任意
                            if(array_intersect($corp_tag_ids,$corpTags)){
                                $flag=false;
                            }
                        }else{
                            //包含所有
                            if(empty(array_diff($corp_tag_ids, $corpTags))){
                                $flag=false;
                            }
                        }
                    }
                    //排除只能标签
                    if(!empty($item['out_tag']['smart_tag_type']) && !empty($item -> out_tag['smart_tag'])){
                        //排除企业标签
                        if($item['out_tag']['smart_tag_type'] == 1){
                            //包含任意
                            if(array_intersect($item['out_tag']['smart_tag'],$smartTags)){
                                $flag=false;
                            }
                        }else{
                            //包含所有
                            if(empty(array_diff($item['out_tag']['smart_tag'], $smartTags))){
                                $flag=false;
                            }
                        }
                    }
                }
                if(!$flag){
                    unset($list[$key]);
                }
            }
            $list->isNotEmpty() && $targetSop = $list->random(1)->first();
            if($targetSop){
                logger()->info('新用户sop标签触发成功'.$targetSop['id']);
                //触发sop
                $robotIds=$this -> applyService -> getApplyRobot(SendConfigConstants::SOP,$targetSop['id']);
                if(!empty($robotIds)){
                    $robotIds=$robotIds->toArray();
                    $robotId=$robotIds[array_rand($robotIds)];
                    $this->createPlan($targetSop, $targetSop['plan'], $targetSop['template_type'], $contactId, $robotId,0, time());
                }
                Db::commit();
                return true;
            }
            Db::commit();
        } catch (\Throwable $ex) {
            Db::rollBack();
            throw New BusinessException(ErrorCode::SERVICE_ERROR,$ex -> getMessage());
        }
    }


    /**
     * 批量触发群邀请
     */
    public function branchTriggerCrowdSop($ids)
    {
        ChRoom::query()->whereIn('id',$ids)->get()->each(function($room){
            //队列里去触发 todo
            $this->triggerCrowdSop($room);
        });
    }


    /**
     * 触发群sop
     */
    public function triggerCrowdSop(ChRoom $room)
    {
        co(function () use ($room) {
            $roomId=$room->room_wxid;
            $number=$room->room_member_count;
            $corpId=$room->corp_id;
            $tags=$room->roomTags()->pluck('tag_id')->toArray();
            //查找
            $robotId=ChRobot::query()->where('user_id',$room->create_user_id)->value('id');
            $ids=$this->applyService->getApplyTargetIds(RobotApplyConstants::SOP,$robotId);
            $list = ChSop::query() -> whereIn('id',$ids) -> where('status',1) -> where('template_type',4) -> get();
            foreach ($list as $key => $item){
                $trigger_condition = $item -> trigger_condition;
                if(array_intersect($tags,$trigger_condition['tags']) && (empty($trigger_condition['people_number']) || $trigger_condition['people_number'] ==  $number)){
                    $this->createPlan($item, $item->plan, $item -> template_type, $roomId, $robotId,0, time(),1);
                    continue;
                }
            }
            return true;
        });

    }

    /**
     * 退订
     */
    public function autoReturn($params)
    {
        var_dump('退订sop');
        $uid=data_get($params,'uid');
        $robotUserId=data_get($params,'user_id');
        $robotId=data_get($params,'robot_id');
        $content=data_get($params,'content');
        $sender=data_get($params,'sender');
        $isRoom=data_get($params,'is_room');
        $tid=$sender;
        if(empty($content['msg_type']) || $content['msg_type']!='text'){
            return false;
        }
        //群暂时不做退订
        if($isRoom){
            $tid=$params['from_room_id'];
            return false;
        }
        $ids=ChSopSendTaskMain::query()->where('robot_id',$robotId)
            ->where('to_id',$tid)
            ->where('is_return',1)
            ->where('return_code',$content['content'])
            ->where('status','!=',5)
            ->pluck('id')->toArray();
        if(empty($ids)) return false;
        ChSopSendTask::query()->whereIn('task_main_id',$ids)->update(['status'=>5]);
        ChSopSendTaskMain::query()->whereIn('id',$ids)->update(['status'=>5]);
        //发送退订成功
        $taskId=$ids[array_rand($ids,1)];
        $content=[[
            'msg_type'=>'text',
            'content'=>'退订成功'
        ]];
        $this->sendRecord($sender, 0, 0, [$robotId], SendConfigConstants::SOP_RETURN, $taskId, time(), $content,0);
        return true;

    }


    /**
     * 自动停止sop计划 todo
     */
    public function autoStopSop()
    {

    }

    /**
     * 循环发送sop任务
     */
    public function loop()
    {
        ChSop::query()->groupBy('main_uid')->chunk(100, function ($chUsers) {
            foreach ($chUsers as $chUser) {
                co(function () use ($chUser) {
                    $date = date("Y-m-d H:i:s", time());
                    ChSopSendTask::query()->where('main_uid',$chUser['main_uid'])->where('status', 1)->where('is_send',0)->where('start_time', '<=', $date)->chunk(100, function ($tasks) {
                        foreach ($tasks as $task) {
                            $robot = container()->get(ChRobotMapper::class)->findById($task -> robot_id);
                            if($robot->login_status !=1){
                                $task->status=2;
                                $task->save();
                                continue;
                            }
                            //第一次给用户发信息时插入退订话术送退订
                            $mainTask=ChSopSendTaskMain::query()->where('id',$task->task_main_id)->first();
                            $content=$task->content;
                            if($mainTask->is_return && !$mainTask->is_send_return && !$task->is_room){
                                $return=[
                                    "msg_type"=>"text",
                                    "content"=>$mainTask->return_text
                                ];
                                array_push($content,$return);
                                ChSopSendTaskMain::query()->where('id',$task->task_main_id)->update([
                                    'is_send_return'=>1
                                ]);
                            }
                            $this->sendRecord($task->to_id, $task->uid, $task->main_uid, [$task -> robot_id], SendConfigConstants::SOP, $task->task_main_id, strtotime($task->start_time), $content,$task->id,$task->is_room);
                            $task -> is_send = 1;
                            $task -> status = 3;
                            $task -> save();
                            ChSop::query()->where('id',$task->sop_id)->increment('send_total');
                            $mainTask->increment('complate_day');
                            if($task->is_last==1){
                                ChSopSendTaskMain::query()->where('id',$task->task_main_id)->update(['status'=>4]);
                                $sop=ChSop::query()->where('id',$task->sop_id)->first();
                                if(!empty($sop)){
                                    if($sop->is_loop == 1){
                                        //判断是否需要循环发送
                                        $nextTime=null;
                                        $mainTaskList=ChSopSendTask::query()-> where('task_main_id',$task->task_main_id)->orderBy('day')->get();
                                        $this->setTaskLoop($mainTaskList,$mainTask);
                                    }
                                }


                            }
                        }
                    });
                });
            }
        });
    }


    public function sendRecord($user_id, $uid, $mainUid, $robotIds, $sendType, $taskId, $startTime, $content,$subTaskId=0, $isRoom = 0)
    {
        if(!empty($robotIds)){
            //创建发送对象
            $recordData = [];
            foreach ($robotIds as $robotId){
                $recordData[] = [
                    'uid' => $uid,
                    'main_uid' => $mainUid,
                    'task_id' => $taskId,
                    'sub_task_id' => $subTaskId,
                    'robot_id' => $robotId,
                    'to_id' => $user_id,
                    'trigger_time' => $startTime,
                    'content' => $content,
                    'msg_total_count' => count($content),
                    'type' => $sendType,
                    'is_room' => $isRoom
                ];
            }
            container()->get(Producer::class)->produce(new SendRecordProducers(
                (new SendRecordProducersDto())
                    ->setMainUid($mainUid)
                    ->setUid((int)$uid)
                    ->setTaskId($taskId)
                    ->setSubTaskId($subTaskId)
                    ->setType($sendType)
                    ->setRecordData($recordData)
                    ->setIsSendNow(true)
            ));
        }
    }


    /**
     * 格式化触发条件
     */
    public function formatTriggerCondition($sop)
    {
        //标签sop
        if($sop->template_type==2){
            $trigger_tag=$sop->trigger_tag;
            $out_tag=$sop->out_tag;
            if(!empty($trigger_tag)){
                if(!empty($trigger_tag['enterprise_tag'])){
                    if(!empty($trigger_tag['enterprise_tag'][0]['corp_id'])){
                        foreach ($trigger_tag['enterprise_tag'] as $k=>$tagIdsInfo){
                            $trigger_tag['enterprise_tag'][$k]['corp_info']=$this->chCorpMapper->findById($tagIdsInfo['corp_id']);
                            $trigger_tag['enterprise_tag'][$k]['enterprise_tag_array']=$this->corpTagService->getTagsByIds($tagIdsInfo['ids']);
                        }
                    }else{
                        $trigger_tag['enterprise_tag_array']=$this->corpTagService->getTagsByIds($trigger_tag['enterprise_tag']);
                    }
                }
                !empty($trigger_tag['smart_tag']) && $trigger_tag['smart_tag_array']=$this->ChSmartTagService->getTagsByIds($trigger_tag['smart_tag']);
            }
            if(!empty($sop->out_tag)){
                if(!empty($out_tag['enterprise_tag'])){
                    if(!empty($out_tag['enterprise_tag'][0]['corp_id'])){
                        foreach ($out_tag['enterprise_tag'] as $k=>$tagIdsInfo){
                            $out_tag['enterprise_tag'][$k]['corp_info']=$this->chCorpMapper->findById($tagIdsInfo['corp_id']);
                            $out_tag['enterprise_tag'][$k]['enterprise_tag_array']=$this->corpTagService->getTagsByIds($tagIdsInfo['ids']);
                        }
                    }else{
                        $out_tag['enterprise_tag_array']=$this->corpTagService->getTagsByIds($out_tag['enterprise_tag']);
                    }
                }
                !empty($out_tag['smart_tag']) && $out_tag['smart_tag_array']=$this->ChSmartTagService->getTagsByIds($out_tag['smart_tag']);
            }
            $sop->trigger_tag=$trigger_tag;
            $sop->out_tag=$out_tag;
        }

        //新客户sop
        if($sop->template_type==3){
            $trigger_tag=$sop->trigger_tag;
            $out_tag=$sop->out_tag;
            $trigger_condition=$sop->trigger_condition;
            if(!empty($trigger_tag)){
                if(!empty($trigger_tag['enterprise_tag'])){
                    if(!empty($trigger_tag['enterprise_tag'][0]['corp_id'])){
                        foreach ($trigger_tag['enterprise_tag'] as $k=>$tagIdsInfo){
                            $trigger_tag['enterprise_tag'][$k]['corp_info']=$this->chCorpMapper->findById($tagIdsInfo['corp_id']);
                            $trigger_tag['enterprise_tag'][$k]['enterprise_tag_array']=$this->corpTagService->getTagsByIds($tagIdsInfo['ids']);
                        }
                    }else{
                        $trigger_tag['enterprise_tag_array']=$this->corpTagService->getTagsByIds($trigger_tag['enterprise_tag']);
                    }
                }
                !empty($trigger_tag['smart_tag']) && $trigger_tag['smart_tag_array']=$this->ChSmartTagService->getTagsByIds($trigger_tag['smart_tag']);
            }
            if(!empty($sop->out_tag)){
                if(!empty($out_tag['enterprise_tag'])){
                    if(!empty($out_tag['enterprise_tag'][0]['corp_id'])){
                        foreach ($out_tag['enterprise_tag'] as $k=>$tagIdsInfo){
                            $out_tag['enterprise_tag'][$k]['corp_info']=$this->chCorpMapper->findById($tagIdsInfo['corp_id']);
                            $out_tag['enterprise_tag'][$k]['enterprise_tag_array']=$this->corpTagService->getTagsByIds($tagIdsInfo['ids']);
                        }
                    }else{
                        $out_tag['enterprise_tag_array']=$this->corpTagService->getTagsByIds($out_tag['enterprise_tag']);
                    }
                }
                !empty($out_tag['smart_tag']) && $out_tag['smart_tag_array']=$this->ChSmartTagService->getTagsByIds($out_tag['smart_tag']);
            }
            $sop->trigger_tag=$trigger_tag;
            $sop->out_tag=$out_tag;

            if(!empty($trigger_condition)){
                $sex_text='';
                foreach ($trigger_condition['sex'] as $sex){
                    if($sex == 0){
                        $sex_text .= "未知";
                    }else if($sex == 1){
                        $sex_text .= "男";
                    }else if($sex == 2){
                        $sex_text .= "女";
                    }
                }

                $trigger_condition['sex_text']=$sex_text;
                $tirgger_text='';
                if($trigger_condition['tirgger_type'] == 1){
                    $tirgger_text = "按性别";
                }else if($trigger_condition['sex'] == 2){
                    $tirgger_text = "加好友直接触发";
                }else if($trigger_condition['sex'] == 3){
                    $tirgger_text = "按标签触发 ";
                }
                $trigger_condition['tirgger_text']=$tirgger_text;
                $sop->trigger_condition=$trigger_condition;
            }
        }

        //群sop
        if($sop->template_type==4){
            $trigger_condition=$sop->trigger_condition;
            if(!empty($trigger_condition)){
                $trigger_condition['tags_array']=$this->ChRoomTagService->getTagsByIds($trigger_condition['tags']);
            }
            $sop->trigger_condition=$trigger_condition;
        }
        return $sop;
    }

    /**
     * 获取sop统计数据
     * @param array $params
     */
    public function getReplyStatisticsList($params=[])
    {
        $pageInfo= $this->mapper->model::query()
            ->with(['user'=>function($q){
                $q->select(['username','id']);
            },'template'=>function($q){
                $q->select(['title','id']);
            }])
            ->where('main_uid',$params['main_uid'])
            ->where('is_track',1)
            ->orderByDesc('id')
            ->when(!empty($params['sop_id']),function ($query) use ($params){
                $query->where('id',$params['sop_id']);
            })
            ->when(!empty($params['template_type']),function ($query) use ($params){
                $query->where('template_type',$params['template_type']);
            })
            ->when(!empty($params['template_id']),function ($query) use ($params){
                $query->where('template_id',$params['template_id']);
            })
            ->whereHas('template',function ($query) use ($params){
                !empty($params['template_name']) && $query->where('title','like',"{$params['template_name']}%");
            })
            ->select(['id','created_at','template_type','template_id','uid','main_uid','track_limit'])
            ->paginate((int)$params['page_size']);
        $pageInfo->getCollection()->transform(function ($item){
            $robot=$this -> applyService -> getApplyRobotsInfo(SendConfigConstants::SOP,$item->id);
            $object_total=ChSopSendTaskMain::query()->where('sop_id',$item->id)->count();
            $countInfo=ChSopSendTaskMain::query()->where('sop_id',$item->id)
                ->selectRaw("SUM(CASE WHEN reply_total > 0 then 1 else 0 end) as reply_total,
            SUM(CASE WHEN loss_total > 0 then 1 else 0 end) as loss_total")
                ->first();
            $loss_total=$countInfo['loss_total'];
            $reply_total=$countInfo['reply_total'];
            $item->loss_rate=$object_total>0?bcdiv((string)($loss_total*100),(string)$object_total,2):0;
            $item->reply_rate=$object_total>0?bcdiv((string)($reply_total*100),(string)$object_total,2):0;
            $item->object_total=$object_total;
            $item->robot=$robot;
            return $item;
        });
        return $this->mapper->setPaginate($pageInfo);
    }


    /**
     * 获取sop统计数据
     * @param array $params
     */
    public function getStatisticsList($params=[])
    {
        $pageInfo= $this->mapper->model::query()
            ->with(['user'=>function($q){
                $q->select(['username','id']);
            },'template'=>function($q){
                $q->select(['title','id']);
            }])
            ->where('uid',$params['uid'])
            ->where('is_track',1)
            ->orderByDesc('id')
            ->select(['id','uid','template_id','custom_total','crowd_total','created_at','template_type','is_track','track_limit','reply_total','loss_total','send_total'])
            ->paginate((int)$params['page_size']);
        $pageInfo->getCollection()->transform(function ($item){
            $item->loss_rate=$item->custom_total?number_format($item->loss_total/$item->custom_total,2)*100:0;
            $item->reply_rate=$item->send_total?number_format($item->reply_total/$item->send_total,2)*100:0;
            return $item;
        });
        return $this->mapper->setPaginate($pageInfo);
    }

    /**
     * 获取sop分日统计数据
     * @param array $params
     */
    public function getStatisticsListByDay($params=[])
    {
        $pageInfo= ChSopSendTask::query()
            ->where('sop_id',$params['sop_id'])
            ->where('is_track',1)
            ->groupBy('day')
            ->selectRaw("content,sum(is_reply) as reply_total,count(1) send_total,SUM(CASE WHEN status = 6 THEN 1 ELSE 0 END) AS loss_total,day")
            ->paginate((int)$params['page_size']);
        //数据录入的时候已经排除了群所以直接count(1)就是总客户数
        $pageInfo->getCollection()->transform(function ($item){
            $item->loss_rate=$item->send_total?number_format($item->loss_total/$item->send_total,2)*100:0;
            $item->reply_rate=$item->send_total?number_format($item->reply_total/$item->send_total,2)*100:0;
            return $item;
        });
        return $this->mapper->setPaginate($pageInfo);
    }



    /**
     * 定时同步统计数据
     */
    public function statisticsSync()
    {
        ChSopSendTask::query()->where('is_track',1)->where('is_statistics', 0)->where('track_time','<=',time())
        ->chunk(100, function ($tasks) {
            foreach ($tasks as $task) {
                //是否流失
                $ls_lose=false;
                //是否回复
                $is_reply=0;

                $to_id=$task->to_id;
                $robot_id=$task->robot_id;
                //检测是否回复
                $contact=ChContact::query()->where('robot_id',$robot_id)->where('user_id',$to_id)->first();
                if($contact){
                    if(ChChatRecord::query()->where('robot_id',$task->robot_id)->where('sender',$task->to_id)->where('send_time','>=',strtotime($task->start_time))->count()){
                        $is_reply=1;
                    }
                    if(!empty($contact['friend_loss_time']) && strtotime($contact['friend_loss_time']) <= $task->track_time && strtotime($contact['friend_loss_time']) >= strtotime($task->start_time))
                    {
                        $ls_lose=true;
                    }
                }
                if($ls_lose){
                    ChSop::query()->where('id',$task->sop_id)->increment('loss_total');
                    ChSopSendTaskMain::query()->where('id',$task->task_main_id)->increment('loss_total');
                }
                //更新统计数据
                if($is_reply){
                    ChSop::query()->where('id',$task->sop_id)->increment('reply_total');
                    ChSopSendTaskMain::query()->where('id',$task->task_main_id)->increment('reply_total');
                }
                $task->is_reply=$is_reply;
                $task->is_statistics=1;
                $task->save();
            }
        });
    }

}